package com.bdqn.t382.practice;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.lang.reflect.Proxy;


public class ValidationProxy {
    public static Object newInstance(Object target) {
        return Proxy.newProxyInstance(target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                new ValidationInvocationHandler(target)
        );
    }

    private static class ValidationInvocationHandler implements InvocationHandler {

        private final Object target;

        public ValidationInvocationHandler(Object target) {
            this.target = target;
        }
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            // 获取接口上的方法信息
            Method[] methods = target.getClass().getInterfaces()[0]
                    .getMethods();
            for (Method m : methods) {
                if (m.getName().equals(method.getName()) &&
                        m.getParameterCount() == args.length) {
                    Parameter[] parameters = m.getParameters();
                    for (int i = 0; i < parameters.length; i++) {
                        if (parameters[i].isAnnotationPresent(Validate.class)) {
                            Validate validate = parameters[i]
                                    .getAnnotation(Validate.class);
                            Object arg = args[i];
                            if (arg instanceof Double) {
                                Double value = (Double) arg;
                                if (validate.notEmpty() && value == null) {
                                    throw new ValidationException("Parameter cannot be null ");
                                }
                                if (!Double.isInfinite(validate.minValue())
                                        && value < validate.minValue()) {
                                    throw new ValidationException("Parameter value is too low:" + value);
                                }
                                if (!Double.isInfinite(validate.maxValue())
                                        && value > validate.maxValue()) {
                                    throw new ValidationException("Parameter value is too high:" + value);
                                }
                            }
                        }
                    }
                } else {
                    throw new IllegalArgumentException("Unsupported parameter type:" + args.getClass().getName());
                }
            }
            return method.invoke(target, args);
        }
    }
}


